package com.ruoyix.im.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
import com.ruoyix.common.core.domain.PageQuery;
import com.ruoyix.common.core.domain.R;
import com.ruoyix.common.core.domain.entity.SysUser;
import com.ruoyix.common.core.page.TableDataInfo;

import com.ruoyix.common.helper.LoginHelper;
import com.ruoyix.im.domain.ImChatGroup;
import com.ruoyix.im.domain.ImChatGroupUser;
import com.ruoyix.im.domain.bo.ImChatGroupUserBo;
import com.ruoyix.im.domain.vo.GroupUserVO;
import com.ruoyix.im.domain.vo.ImChatGroupUserVo;
import com.ruoyix.im.mapper.ImChatGroupMapper;
import com.ruoyix.im.mapper.ImChatGroupUserMapper;
import com.ruoyix.im.service.IImChatGroupService;
import com.ruoyix.im.service.IImChatGroupUserService;
import com.ruoyix.im.websocket.ImConfigConst;
import com.ruoyix.im.websocket.TioWebsocketStarter;
import com.ruoyix.system.mapper.SysUserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestParam;
import org.tio.core.Tio;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 聊天群成员Service业务层处理
 *
 * @author ruoyi
 * @date 2024-05-27
 */
@RequiredArgsConstructor
@Service
public class ImChatGroupUserServiceImpl extends ServiceImpl<ImChatGroupUserMapper, ImChatGroupUser> implements IImChatGroupUserService {

    private final ImChatGroupUserMapper baseMapper;
    private final ImChatGroupMapper imChatGroupMapper;
    private final TioWebsocketStarter tioWebsocketStarter;
    private final SysUserMapper sysUserMapper;

    /**
     * 查询聊天群成员
     */
    @Override
    public ImChatGroupUserVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询聊天群成员列表
     */
    @Override
    public TableDataInfo<ImChatGroupUserVo> queryPageList(ImChatGroupUserBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ImChatGroupUser> lqw = buildQueryWrapper(bo);
        Page<ImChatGroupUserVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询聊天群成员列表
     */
    @Override
    public List<ImChatGroupUserVo> queryList(ImChatGroupUserBo bo) {
        LambdaQueryWrapper<ImChatGroupUser> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ImChatGroupUser> buildQueryWrapper(ImChatGroupUserBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ImChatGroupUser> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getGroupId() != null, ImChatGroupUser::getGroupId, bo.getGroupId());
        lqw.eq(bo.getUserId() != null, ImChatGroupUser::getUserId, bo.getUserId());
        lqw.eq(bo.getVerifyUserId() != null, ImChatGroupUser::getVerifyUserId, bo.getVerifyUserId());
        lqw.eq(bo.getAdminFlag() != null, ImChatGroupUser::getAdminFlag, bo.getAdminFlag());
        lqw.eq(bo.getUserStatus() != null, ImChatGroupUser::getUserStatus, bo.getUserStatus());
        return lqw;
    }

    /**
     * 新增聊天群成员
     */
    @Override
    public Boolean insertByBo(ImChatGroupUserBo bo) {
        ImChatGroupUser add = BeanUtil.toBean(bo, ImChatGroupUser.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改聊天群成员
     */
    @Override
    public Boolean updateByBo(ImChatGroupUserBo bo) {
        ImChatGroupUser update = BeanUtil.toBean(bo, ImChatGroupUser.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ImChatGroupUser entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除聊天群成员
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

//    public R<Page<GroupUserVO>> getGroupUserByStatus(Long groupId, Integer userStatus, Long current, Long size) {
//        Long userId = LoginHelper.getUserId();
//
//        // 初始化分页参数
//        Page<ImChatGroupUser> page = new Page<>(current, size);
//        LambdaQueryChainWrapper<ImChatGroupUser> lambdaQuery = lambdaQuery();
//
//        // 检查群组ID
//        if (groupId != null) {
//            ImChatGroup chatGroup = imChatGroupMapper.selectById(id)(groupId);
//            if (chatGroup == null) {
//                return R.fail("群组不存在！");
//            }
//
//            if (chatGroup.getGroupType().intValue() == ImConfigConst.GROUP_TOPIC) {
//                return R.fail("话题没有用户！");
//            }
//
//            // 检查用户审核权限
//            boolean hasAdminPermission = imChatGroupUserService.lambdaQuery()
//                .eq(ImChatGroupUser::getGroupId, groupId)
//                .eq(ImChatGroupUser::getUserId, userId)
//                .eq(ImChatGroupUser::getAdminFlag, ImConfigConst.ADMIN_FLAG_TRUE)
//                .count() > 0;
//
//            if (!hasAdminPermission) {
//                return R.fail("没有审核权限！");
//            }
//            lambdaQuery.eq(ImChatGroupUser::getGroupId, groupId);
//        } else {
//            // 检查用户是否管理任何群组
//            List<Long> managedGroupIds = imChatGroupUserService.lambdaQuery()
//                .eq(ImChatGroupUser::getUserId, userId)
//                .eq(ImChatGroupUser::getAdminFlag, ImConfigConst.ADMIN_FLAG_TRUE)
//                .list()
//                .stream()
//                .map(ImChatGroupUser::getGroupId)
//                .collect(Collectors.toList());
//
//            if (managedGroupIds.isEmpty()) {
//                return R.ok();
//            }
//            lambdaQuery.in(ImChatGroupUser::getGroupId, managedGroupIds);
//        }
//
//        // 用户状态过滤
//        if (userStatus != null) {
//            lambdaQuery.eq(ImChatGroupUser::getUserStatus, userStatus);
//        }
//
//        // 分页和排序
//        lambdaQuery.orderByDesc(ImChatGroupUser::getCreateTime).page(page);
//
//        // 获取群组用户列表
//        List<ImChatGroupUser> records = page.getRecords();
//        if (records.isEmpty()) {
//            return R.ok(new Page<>());
//        }
//
//        // 获取群组名称
//        List<Long> groupIds = records.stream().map(ImChatGroupUser::getGroupId).distinct().collect(Collectors.toList());
//        Map<Long, String> groupNameMap = imChatGroupService.lambdaQuery()
//            .select(ImChatGroup::getId, ImChatGroup::getGroupName)
//            .in(ImChatGroup::getId, groupIds)
//            .list()
//            .stream()
//            .collect(Collectors.toMap(ImChatGroup::getId, ImChatGroup::getGroupName));
//
//        // 获取用户信息
//        List<Long> userIds = records.stream().map(ImChatGroupUser::getUserId).distinct().collect(Collectors.toList());
//        Map<Long, SysUser> userMap = sysUserMapper.selectBatchIds(userIds).stream()
//            .collect(Collectors.toMap(SysUser::getUserId, user -> user));
//
//        // 组装VO
//        List<GroupUserVO> groupUserVOList = records.stream().map(record -> {
//            GroupUserVO groupUserVO = new GroupUserVO();
//            BeanUtils.copyProperties(record, groupUserVO);
//            groupUserVO.setGroupName(groupNameMap.get(record.getGroupId()));
//
//            SysUser user = userMap.get(record.getUserId());
//            if (user != null) {
//                groupUserVO.setUsername(user.getUserName());
//                groupUserVO.setAvatar(user.getAvatar());
//            }
//
//            return groupUserVO;
//        }).collect(Collectors.toList());
//
//        // 设置结果分页信息
//        Page<GroupUserVO> result = new Page<>(current, size);
//        result.setRecords(groupUserVOList);
//        result.setTotal(page.getTotal());
//
//        return R.ok(result);
//    }



    public R<Page<GroupUserVO>> getGroupUserByStatus (Long groupId, Integer userStatus, Long current, Long size){
        Long userId = LoginHelper.getUserId();

        Page<ImChatGroupUser> page = new Page<>();
        page.setCurrent(current);
        page.setSize(size);
        LambdaQueryChainWrapper<ImChatGroupUser> lambdaQuery = lambdaQuery();
        if (groupId != null) {
            ImChatGroup chatGroup = imChatGroupMapper.selectById(groupId);
            if (chatGroup == null) {
                return R.fail("群组不存在！");
            }

            if (chatGroup.getGroupType().intValue() == ImConfigConst.GROUP_TOPIC) {
                return R.fail("话题没有用户！");
            }

            LambdaQueryChainWrapper<ImChatGroupUser> groupLambdaQuery = lambdaQuery();
            groupLambdaQuery.eq(ImChatGroupUser::getGroupId, groupId);
            groupLambdaQuery.eq(ImChatGroupUser::getUserId, userId);
            groupLambdaQuery.eq(ImChatGroupUser::getAdminFlag, ImConfigConst.ADMIN_FLAG_TRUE);
            ImChatGroupUser groupUser = groupLambdaQuery.one();
            if (groupUser == null) {
                return R.fail("没有审核权限！");
            }
            lambdaQuery.eq(ImChatGroupUser::getGroupId, groupId);
        } else {
            LambdaQueryChainWrapper<ImChatGroupUser> userLambdaQuery = lambdaQuery();
            userLambdaQuery.eq(ImChatGroupUser::getUserId, userId);
            userLambdaQuery.eq(ImChatGroupUser::getAdminFlag, ImConfigConst.ADMIN_FLAG_TRUE);
            List<ImChatGroupUser> groupUsers = userLambdaQuery.list();
            if (CollectionUtils.isEmpty(groupUsers)) {
                // 该用户没有管理任何群
                return R.ok();
            } else {
                List<Long> groupIds = groupUsers.stream().map(ImChatGroupUser::getGroupId).collect(Collectors.toList());
                lambdaQuery.in(ImChatGroupUser::getGroupId, groupIds);
            }
        }

        if (userStatus != null) {
            lambdaQuery.eq(ImChatGroupUser::getUserStatus, userStatus);
        }

        lambdaQuery.orderByDesc(ImChatGroupUser::getCreateTime).page(page);

        List<GroupUserVO> groupUserVOList = new ArrayList<>(page.getRecords().size());
        List<ImChatGroupUser> records = page.getRecords();
        Map<Long, List<ImChatGroupUser>> map = records.stream().collect(Collectors.groupingBy(ImChatGroupUser::getGroupId));

        LambdaQueryChainWrapper<ImChatGroup> imChatGroupLambdaQueryChainWrapper = ChainWrappers.lambdaQueryChain(imChatGroupMapper, ImChatGroup.class);

        List<ImChatGroup> groups = imChatGroupLambdaQueryChainWrapper.select(ImChatGroup::getId, ImChatGroup::getGroupName).in(ImChatGroup::getId, map.keySet()).list();
        Map<Long, String> collect = groups.stream().collect(Collectors.toMap(ImChatGroup::getId, ImChatGroup::getGroupName));
        map.forEach((key, value) -> {
            String groupName = collect.get(key);
            value.forEach(g -> {
                GroupUserVO groupUserVO = new GroupUserVO();
                BeanUtils.copyProperties(g, groupUserVO);
                groupUserVO.setGroupName(groupName);
                SysUser user =sysUserMapper.selectUserById(groupUserVO.getUserId());
                if (user != null) {
                    groupUserVO.setUsername(user.getUserName());
                    groupUserVO.setAvatar(user.getAvatar());
                }
                groupUserVOList.add(groupUserVO);
            });
        });

        Page<GroupUserVO> result = new Page<>();
        result.setRecords(groupUserVOList);
        result.setTotal(page.getTotal());
        result.setCurrent(page.getCurrent());
        result.setSize(page.getSize());
        return R.ok(result);
    }



    public R<Void> enterGroup(Long id, String remark) {
        ImChatGroup chatGroup = imChatGroupMapper.selectById(id);
        if (chatGroup == null) {
            return R.fail("群组不存在！");
        }

        if (chatGroup.getGroupType().intValue() == ImConfigConst.GROUP_TOPIC) {
            return R.fail("话题无需申请！");
        }

        Long userId = LoginHelper.getUserId();

        LambdaQueryChainWrapper<ImChatGroupUser> lambdaQuery = lambdaQuery();
        lambdaQuery.eq(ImChatGroupUser::getGroupId, id);
        lambdaQuery.eq(ImChatGroupUser::getUserId, userId);
        ImChatGroupUser groupUser = lambdaQuery.one();
        if (groupUser != null) {
            return R.fail("重复申请！");
        }

        ImChatGroupUser imChatGroupUser = new ImChatGroupUser();
        imChatGroupUser.setGroupId(id);
        imChatGroupUser.setUserId(userId);
        if (StringUtils.hasText(remark)) {
            imChatGroupUser.setRemark(remark);
        }
        if (chatGroup.getInType() == 0) {
            imChatGroupUser.setUserStatus(ImConfigConst.GROUP_USER_STATUS_PASS);
        } else {
            imChatGroupUser.setUserStatus(ImConfigConst.GROUP_USER_STATUS_NOT_VERIFY);
        }
        boolean isSuccess = save(imChatGroupUser);
        if (isSuccess && chatGroup.getInType() == 1) {
            Tio.bindGroup(tioWebsocketStarter.getServerTioConfig(), String.valueOf(userId), String.valueOf(id));
        }
        return R.ok();
    }

    public R<Void> changeUserStatus(Long groupId, Long userId, Long userStatus, Long oldUserStatus) {
        ImChatGroup chatGroup = imChatGroupMapper.selectById(groupId);
        if (chatGroup == null) {
            return R.fail("群组不存在！");
        }

        if (chatGroup.getGroupType().intValue() == ImConfigConst.GROUP_TOPIC) {
            return R.fail("话题无需操作！");
        }

        Long currentUserId = LoginHelper.getUserId();
        LambdaQueryChainWrapper<ImChatGroupUser> lambdaQuery = lambdaQuery();
        lambdaQuery.eq(ImChatGroupUser::getGroupId, groupId);
        lambdaQuery.eq(ImChatGroupUser::getUserId, currentUserId);
        lambdaQuery.eq(ImChatGroupUser::getAdminFlag, ImConfigConst.ADMIN_FLAG_TRUE);
        ImChatGroupUser groupUser = lambdaQuery.one();
        if (groupUser == null) {
            return R.fail("没有审核权限！");
        }

        boolean isSuccess;
        if (userStatus == ImConfigConst.GROUP_USER_STATUS_BAN) {
            LambdaUpdateChainWrapper<ImChatGroupUser> lambdaUpdate = lambdaUpdate();
            lambdaUpdate.eq(ImChatGroupUser::getGroupId, groupId);
            lambdaUpdate.eq(ImChatGroupUser::getUserId, userId);
            lambdaUpdate.eq(ImChatGroupUser::getAdminFlag, ImConfigConst.ADMIN_FLAG_FALSE);
            lambdaUpdate.eq(ImChatGroupUser::getUserStatus, oldUserStatus);
            isSuccess = lambdaUpdate.remove();
        } else {
            LambdaUpdateChainWrapper<ImChatGroupUser> lambdaUpdate = lambdaUpdate();
            lambdaUpdate.eq(ImChatGroupUser::getGroupId, groupId);
            lambdaUpdate.eq(ImChatGroupUser::getUserId, userId);
            lambdaUpdate.eq(ImChatGroupUser::getAdminFlag, ImConfigConst.ADMIN_FLAG_FALSE);
            lambdaUpdate.eq(ImChatGroupUser::getUserStatus, oldUserStatus);
            lambdaUpdate.set(ImChatGroupUser::getUserStatus, userStatus);
            if (userStatus == ImConfigConst.GROUP_USER_STATUS_PASS) {
                lambdaUpdate.set(ImChatGroupUser::getVerifyUserId, currentUserId);
            }
            isSuccess = lambdaUpdate.update();
        }
        if (isSuccess && userStatus.equals(ImConfigConst.GROUP_USER_STATUS_PASS)) {
            Tio.bindGroup(tioWebsocketStarter.getServerTioConfig(), String.valueOf(userId), String.valueOf(groupId));
        } else if (isSuccess && userStatus.intValue() == ImConfigConst.GROUP_USER_STATUS_BAN &&
            (oldUserStatus.intValue() == ImConfigConst.GROUP_USER_STATUS_PASS ||
                oldUserStatus.intValue() == ImConfigConst.GROUP_USER_STATUS_SILENCE)) {
            Tio.unbindGroup(tioWebsocketStarter.getServerTioConfig(), String.valueOf(userId), String.valueOf(groupId));
        }

        if (isSuccess) {
            return R.ok();
        } else {
            return R.fail("修改失败！");
        }
    }


    public R<Void> changeAdmin(Long groupId, Long userId, Boolean adminFlag) {
        ImChatGroup chatGroup = imChatGroupMapper.selectById(groupId);
        if (chatGroup == null) {
            return R.fail("群组不存在！");
        }

        if (chatGroup.getGroupType().intValue() == ImConfigConst.GROUP_TOPIC) {
            return R.fail("话题无需操作！");
        }

        Long currentUserId = LoginHelper.getUserId();
        assert currentUserId != null;
        if (chatGroup.getMasterUserId().intValue() != currentUserId.intValue()) {
            return R.fail("群主才能设置管理员！");
        }

        LambdaUpdateChainWrapper<ImChatGroupUser> lambdaUpdate = lambdaUpdate();
        lambdaUpdate.eq(ImChatGroupUser::getGroupId, groupId);
        lambdaUpdate.eq(ImChatGroupUser::getUserId, userId);
        lambdaUpdate.set(ImChatGroupUser::getAdminFlag, adminFlag);

        lambdaUpdate.update();
        return R.ok();
    }

    public R<Void> getGroupUser(Long id) {
        ImChatGroup chatGroup = imChatGroupMapper.selectById(id);
        if (chatGroup == null) {
            return R.fail("群组不存在！");
        }

        if (chatGroup.getGroupType().intValue() == ImConfigConst.GROUP_TOPIC) {
            return R.fail("话题无需操作！");
        }

        Long userId = LoginHelper.getUserId();

        assert userId != null;
        if (chatGroup.getMasterUserId().intValue() == userId.intValue()) {
            //转让群
            LambdaQueryChainWrapper<ImChatGroupUser> wrapper = lambdaQuery();
            wrapper.ne(ImChatGroupUser::getUserId, userId);
            wrapper.last("order by admin_flag desc, create_time asc limit 1");
            ImChatGroupUser one = wrapper.one();

            if (one == null) {
                //除了群主没别人，直接删除
                imChatGroupMapper.deleteById(id);
            } else {
                LambdaUpdateChainWrapper<ImChatGroup> groupUpdate = ChainWrappers.lambdaUpdateChain(imChatGroupMapper);
                groupUpdate.eq(ImChatGroup::getId, id);
                groupUpdate.set(ImChatGroup::getMasterUserId, one.getUserId());
                groupUpdate.update();
                LambdaUpdateChainWrapper<ImChatGroupUser> groupUserUpdate = lambdaUpdate();
                groupUserUpdate.eq(ImChatGroupUser::getId, one.getId());
                groupUserUpdate.set(ImChatGroupUser::getAdminFlag, ImConfigConst.ADMIN_FLAG_TRUE);
                groupUserUpdate.update();
            }
        }

        LambdaUpdateChainWrapper<ImChatGroupUser> lambdaUpdate = lambdaUpdate();
        lambdaUpdate.eq(ImChatGroupUser::getGroupId, id);
        lambdaUpdate.eq(ImChatGroupUser::getUserId, userId);
        boolean isSuccess = lambdaUpdate.remove();
        if (isSuccess) {
            Tio.unbindGroup(tioWebsocketStarter.getServerTioConfig(), String.valueOf(userId), String.valueOf(id));
        }
        return R.ok();
    }


    public R<Page<GroupUserVO>> getPagePoetryResult(Long groupId, Long current, Long size) {
        ImChatGroup chatGroup = imChatGroupMapper.selectById(groupId);
        if (chatGroup == null) {
            return R.fail("群组不存在！");
        }

        if (chatGroup.getGroupType().intValue() == ImConfigConst.GROUP_TOPIC) {
            return R.fail("话题没有用户！");
        }

        Long userId = LoginHelper.getUserId();
        LambdaQueryChainWrapper<ImChatGroupUser> wrapper = lambdaQuery();
        wrapper.eq(ImChatGroupUser::getUserId, userId);
        wrapper.eq(ImChatGroupUser::getGroupId, groupId);
        wrapper.in(ImChatGroupUser::getUserStatus, ImConfigConst.GROUP_USER_STATUS_PASS, ImConfigConst.GROUP_USER_STATUS_SILENCE);
        Long count = wrapper.count();
        if (count < 1) {
            return R.fail("未加群！");
        }

        Page<ImChatGroupUser> page = new Page<>();
        page.setCurrent(current);
        page.setSize(size);
        LambdaQueryChainWrapper<ImChatGroupUser> lambdaQuery = lambdaQuery();
        lambdaQuery.eq(ImChatGroupUser::getGroupId, groupId);
        lambdaQuery.in(ImChatGroupUser::getUserStatus, ImConfigConst.GROUP_USER_STATUS_PASS, ImConfigConst.GROUP_USER_STATUS_SILENCE);
        lambdaQuery.orderByAsc(ImChatGroupUser::getCreateTime).page(page);

        List<GroupUserVO> groupUserVOList = new ArrayList<>(page.getRecords().size());
        List<ImChatGroupUser> records = page.getRecords();
        records.forEach(g -> {
            GroupUserVO groupUserVO = new GroupUserVO();
            BeanUtils.copyProperties(g, groupUserVO);
            groupUserVO.setGroupName(chatGroup.getGroupName());
            SysUser user =  sysUserMapper.selectUserById(groupUserVO.getUserId());
            if (user != null) {
                groupUserVO.setUsername(user.getUserName());
                groupUserVO.setAvatar(user.getAvatar());
            }
            groupUserVOList.add(groupUserVO);
        });

        Page<GroupUserVO> result = new Page<>();
        result.setRecords(groupUserVOList);
        result.setTotal(page.getTotal());
        result.setCurrent(page.getCurrent());
        result.setSize(page.getSize());
        return R.ok(result);
    }

}
